package com.hollysys.hollimsa.biz.istio.destinationrule.service.impl;


import com.hollysys.hollimsa.biz.istio.destinationrule.dao.DestinationRuleDao;
import com.hollysys.hollimsa.biz.istio.destinationrule.domain.DestinationRuleDTO;
import com.hollysys.hollimsa.biz.istio.destinationrule.domain.DestinationRuleDetailDTO;
import com.hollysys.hollimsa.biz.istio.destinationrule.domain.DestinationRuleVO;
import com.hollysys.hollimsa.biz.istio.destinationrule.domain.SimpleDetailDestinationRuleDTO;
import com.hollysys.hollimsa.biz.istio.destinationrule.service.DestinationRuleService;
import com.hollysys.hollimsa.common.filter.tenantinfo.TenantInfoContext;
import com.hollysys.hollimsa.common.tools.JacksonUtil;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import me.snowdrop.istio.api.networking.v1beta1.*;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class DestinationRuleServiceImpl implements DestinationRuleService {

    @Autowired
    private DestinationRuleDao destinationRuleDao;


    @Override
    public List<DestinationRuleDTO> listDestinationRule() {
        final String namespace = TenantInfoContext.getTenantNS();
        return destinationRuleDao.listDestinationRule(namespace).stream().map(x -> {
            DestinationRuleDTO dto = new DestinationRuleDTO();
            dto.setName(x.getMetadata().getName());
            dto.setHost(x.getSpec().getHost());
            return dto;
        }).collect(Collectors.toList());
    }


    /**
     * 创建或更新组件
     *
     * @param destinationRuleVO 组件信息表单
     * @return
     */
    @Override
    public boolean createOrReplaceDestinationRule(DestinationRuleVO destinationRuleVO) {
        final String namespace = TenantInfoContext.getTenantNS();

        final List<Subset> subsets = Arrays.stream(destinationRuleVO.getSubsets()).map(
            subset -> new SubsetBuilder().addToLabels(JacksonUtil.fromJSON(subset.getLabels(), HashMap.class)).withName(subset.getName()).build()
        ).collect(Collectors.toList());

        final ObjectMeta objectMeta = new ObjectMetaBuilder().withName(destinationRuleVO.getName()).withNamespace(namespace).build();

        final DestinationRuleSpec spec = new DestinationRuleSpecBuilder().withHost(destinationRuleVO.getHost()).withExportTo(".").withSubsets(subsets).build();

        final DestinationRule destinationRule = new DestinationRuleBuilder().withMetadata(objectMeta).withSpec(spec).build();

        destinationRuleDao.createOrReplaceDestinationRule(destinationRule, namespace);
        return Boolean.TRUE;
    }

    @Override
    public boolean deleteDestinationRule(String name) {
        final String namespace = TenantInfoContext.getTenantNS();
        return destinationRuleDao.deleteDestinationRule(name, namespace);
    }


    /**
     * 获取组件详情信息
     *
     * @param drName 组件名称
     * @return
     */
    @Override
    public DestinationRuleDetailDTO getDestinationRuleDetail(String drName) {
        final String namespace = TenantInfoContext.getTenantNS();
        DestinationRule destinationRule = destinationRuleDao.getDestinationRuleDetail(drName, namespace);

        DestinationRuleDetailDTO.Subset[] subsets = destinationRule.getSpec().getSubsets().stream().map(subset -> {
            String name = subset.getName();
            Map<String, String> labels = subset.getLabels();
            return DestinationRuleDetailDTO.Subset.builder().name(name).labels(JacksonUtil.toJSON(labels)).build();
        }).toArray(DestinationRuleDetailDTO.Subset[]::new);


        return DestinationRuleDetailDTO.builder()
            .createdAt(DateTime.parse(destinationRule.getMetadata().getCreationTimestamp()).toDate())
            .name(destinationRule.getMetadata().getName())
            .host(destinationRule.getSpec().getHost())
            .subsets(subsets).build();
    }


    /**
     * 获取组件下拉数据
     *
     * @return
     */
    @Override
    public SimpleDetailDestinationRuleDTO drData4DropDown() {
        final String namespace = TenantInfoContext.getTenantNS();

        Stream<DestinationRule> destinationRuleStream1 = destinationRuleDao.drData4DropDown(namespace).stream();
        Stream<DestinationRule> destinationRuleStream2 = destinationRuleDao.drData4DropDown(namespace).stream();

        List<SimpleDetailDestinationRuleDTO.DictDestinationHostItem> hostItems = destinationRuleStream1.map(item ->
            SimpleDetailDestinationRuleDTO.DictDestinationHostItem.builder().label(item.getMetadata().getName()).value(item.getSpec().getHost()).build()
        ).collect(Collectors.toList());

        List<List<SimpleDetailDestinationRuleDTO.DictDestinationSubsetItemItem>> dictDestinationSubset = destinationRuleStream2.map(item -> item.getSpec().getSubsets().stream().map(subset ->
            SimpleDetailDestinationRuleDTO.DictDestinationSubsetItemItem.builder()
                .label(subset.getName())
                .value(subset.getName()).build())
            .collect(Collectors.toList())
        ).collect(Collectors.toList());

        return SimpleDetailDestinationRuleDTO.builder().dictDestinationHost(hostItems).dictDestinationSubset(dictDestinationSubset).build();
    }
}
